#include "base/logging.h"
#include "dispatch_message_task.h"
#include "shop_waiter_map.h"
#include "redis_adapter.h"

#include "im/common/common.h"
#include "im/adapters/session_adapter.h"
#include "im/adapters/message_outlet_adapter.h"
#include "im/adapters/message_history_adapter.h"
#include "im/adapters/recent_contact_adapter.h"
#include "im/adapters/user_profile_adapter.h"

namespace imserver {

extern RedisAdapter * g_redis_adapter;

void DispatchFromCustomerMessage(ImMessage & message, int64_t mapped_receiver) {
  // 追加历史消息时，要按(customer, shop)来追加
  message.__set_via_shop(message.receiver);
  UserProfile user_profile;
  int ret = UserProfileAdapter::Instance().Get(message.receiver, &user_profile, 3);
  if (ret == 0) {
    if (message.receiver == 127646892) {
      user_profile.__set_shop_name("穆的小店");
      user_profile.__set_shop_url("http://bang.360.cn/");
    }

    if (user_profile.__isset.shop_name) {
      message.__set_via_shop_name(user_profile.shop_name);
    }

    if (user_profile.__isset.shop_url) {
      message.__set_via_shop_url(user_profile.shop_url);
    }
  }

  if (message.seq_id > 0) {
    MessageHistoryAdapter::Instance().AddMessage(message, 2);
    LOG_DEBUG("Add call center message " << message.seq_id << " shop=" << message.receiver << " sender=" << message.sender);
  }
  RecentContactAdapter::Instance().Add(message.sender, message.receiver, 2);
  LOG_DEBUG("to waiter set via_shop=" << message.receiver << " sender=" << message.sender);
  
  g_redis_adapter->LinkWaiterCustomerShop(mapped_receiver, message.sender, message.receiver);

  if (ShopWaiterMap::Instance().IsOnlineWaiter(mapped_receiver)) {
    SessionList session_list;
    
    if (0 != SessionAdapter::Instance().GetSessionList(mapped_receiver, &session_list, 2)) {
      LOG_WARN("GetSessionList error, receiver=" << mapped_receiver);
    }
    
    for(size_t i = 0; i < session_list.size(); ++i) {
      if (session_list[i].timestamp - time(NULL) > 300) {
        // TODO : remove stale session
        LOG_WARN("session " << session_list[i].key << " timeout!");
        continue;
      }
      message.receiver = mapped_receiver;
      if (MessageOutletAdapter::Instance().DistributeMessage(session_list[i].key, message, 2) == 0) {
        LOG_DEBUG("DistributeMessage ok. sender=" << message.sender << " receiver=" << message.receiver << " session=" << session_list[i].key);
      } else {
        LOG_WARN("DistributeMessage err. sender=" << message.sender << " receiver=" << message.receiver << " session=" << session_list[i].key);
      }
    }
  } else {
    // 1. 告知sender, shop不在线
    SessionList sender_sessions;
    SessionAdapter::Instance().GetSessionList(message.sender, &sender_sessions, 2);
    
    ImMessage notify_message;
    notify_message.sender = message.receiver;
    notify_message.receiver = message.sender;
    notify_message.timestamp = time(NULL);

    SetMessageType(notify_message, MSG_TYPE_OFFLINE_NOTIFY);
    std::stringstream body;
    body << "对方不在线，上线后会收到您的消息";
    notify_message.body = body.str();

    for(size_t i = 0; i < sender_sessions.size(); ++i) {
      int res = MessageOutletAdapter::Instance().DistributeMessage(sender_sessions[i].key, notify_message, 2);
      LOG_DEBUG("notify message type=" << MessageType(notify_message) << message.receiver << " reveiver=" 
               << notify_message.receiver << " res=" << res);
    }
  }
}

void DispatchToCustomerMessage(ImMessage & message) {
  SessionList session_list;
  if (0 != SessionAdapter::Instance().GetSessionList(message.receiver, &session_list, 2)) {
    LOG_WARN("GetSessionList error, receiver=" << message.receiver);
  }
  g_redis_adapter->LinkWaiterCustomerShop(message.sender, message.receiver, message.via_shop);

  int count = 0;
  message.sender = message.via_shop;
  for(size_t i = 0; i < session_list.size(); ++i) {
    if (session_list[i].timestamp - time(NULL) > 300) {
      // TODO : remove stale session
      LOG_WARN("session " << session_list[i].key << " timeout!");
      continue;
    }
    if (MessageOutletAdapter::Instance().DistributeMessage(session_list[i].key, message, 2) == 0) {
      LOG_DEBUG("DistributeMessage ok. sender=" << message.sender << " receiver=" << message.receiver << " session=" << session_list[i].key);
      ++count;
    } else {
      LOG_WARN("DistributeMessage err. sender=" << message.sender << " receiver=" << message.receiver << " session=" << session_list[i].key);
    }
  }
  if (count > 0) {
    message.flags |= MSG_FLAG_READ;
  }

  LOG_INFO("message " << message.seq_id << " sender=" << message.sender << " receiver=" << message.receiver << " delivery=" << count);
  RecentContactAdapter::Instance().Add(message.via_shop, message.receiver, 2);

  if (message.seq_id > 0) {
    MessageHistoryAdapter::Instance().AddMessage(message, 2); // 发消息的waiter可以看到该历史消息, 对方不会
  }
}

void DispatchMessageTask::run() {
  LOG_DEBUG("DispatchMessageTask executed");
  // TODO : 如果sender是shop, 就提示错误，而不予转发！

  int64_t mapped_sender = 0;
  int64_t mapped_receiver = 0;
  if (message_.__isset.via_shop) {
    DispatchToCustomerMessage(message_);
    return;
  }

  ShopWaiterMap::Instance().MapSenderReceiver(message_.sender, message_.receiver, &mapped_sender, &mapped_receiver);
  if (mapped_receiver > 0 && mapped_receiver != message_.receiver) { // 来自客户的消息
    DispatchFromCustomerMessage(message_, mapped_receiver);
    return;
  }

  if (mapped_sender > 0 && mapped_sender != message_.sender) { // 来自客户的消息
    message_.__set_via_shop(mapped_sender);
    DispatchToCustomerMessage(message_);
    return;
  }
  DispatchDefaultMessage(message_);
}

}


